//LBP解释语言
//c 2025 Obsever Studio
#include<iostream>
#include<fstream>
#include<sstream>
#include<vector>
#include<set>
#include<map>
#include<cstdlib>
#include<ctime>
#include<cctype>
#include<functional>
#include<string.h>
using namespace std;

//BR
#define BR goto
#define BRn(a) if(a<0)goto
#define BRz(a) if(a==0)goto
#define BRp(a) if(a>0)goto
#define BRnz(a) if(a<=0)goto
#define BRnp(a) if(a!=0)goto
#define BRzp(a) if(a>=0)goto

vector<string> ops;//各个拆分出的部分
vector<void*> litter;
struct types;
struct type{
	union{
		//Unit/Void //0
		char c;//1
		int i;//2
		void *vp;//3
		int *ip;//4
		const char *cp;//5
		types *kids;//6
		type *tp;//7
	}data;
	short ty;
};
struct types{
	type *data;
	int size;
};
map<string,function<types()>> tokens;
map<string,types> vm;
int *line;int cache_be_used=0;

// 转义字符解析函数
char parse_escape_char(char esc){
	switch(esc){
		case 'n': return '\n';
		case 't': return '\t';
		case 'r': return '\r';
		case '0': return '\0';
		case '\'': return '\'';
		case '"': return '"';
		case '[': return '[';
		case ']': return ']';
		default: return esc; // 未知转义字符保持原样
	}
}

// 字符串转义解析
string parse_escape_string(const string& s){
	string result;
	for(int i=0;i<s.length();i++){
		if(s[i]=='[' && i+2<s.length() && s[i+2]==']'){
			result += parse_escape_char(s[i+1]);
			i += 2; // 跳过转义序列
		}else{
			result += s[i];
		}
	}
	return result;
}

types pexpl(){
	string t=ops[*line];
	if(t[0]>='0'&&t[0]<='9'){
		types t2;
		t2.data=new type[1];
		t2.size=1;
		litter.push_back(t2.data);
		t2.data[0].data.i=atoi(t.c_str());
		t2.data[0].ty=2;
		return t2;
	}else if(t[0]=='\''&&t.size()>=3&&t.back()=='\''){
		//字符解析
		string inner=t.substr(1, t.size()-2);
		char c_val;
		if(inner.size()==3 && inner[0]=='[' && inner[2]==']'){
			c_val=parse_escape_char(inner[1]);
		}else if(inner.size()==1){
			c_val=inner[0];
		}else{
			c_val='\0';
		}
		types t2;
		t2.data=new type[1];
		t2.size=1;
		litter.push_back(t2.data);
		t2.data[0].ty=1;
		t2.data[0].data.c=c_val;
		return t2;
	}else if(t[0]=='\"'&&t.size()>=2&&t.back()=='\"'){
		//字符串解析
		string inner=t.substr(1, t.size()-2);
		string parsed=parse_escape_string(inner);
		// 分配内存存储字符串
		char *str=new char[parsed.size() + 1];
		strcpy(str,parsed.c_str());
		types t2;
		t2.data=new type[1];
		t2.size=1;
		litter.push_back(t2.data);
		litter.push_back(str);//记录字符串内存
		t2.data[0].ty=5;
		t2.data[0].data.cp=str;
		return t2;
	}else if(vm.find(t)!=vm.end()){
		return vm[t];
	}else if(tokens.find(t)!=tokens.end()){
		return tokens[t]();
	}else{
		cout<<"Undefined token : "<<t<<"\n";
		exit(4);
	}
	types t2;
	t2.data=new type[1];
	t2.size=1;
	litter.push_back(t2.data);
	t2.data[0].ty=0;// Unit/Void
	return t2;
}

void clean();
function<void()> ed[2]{
	[]{},
	[]{
		clean();
		cache_be_used=0;
	}
};
//解释器启动!
types explain(){
	int &line=*::line;
	while(1){
		try{
			pexpl();
		}catch(types r){
			return r;
		}
		//the end
		line++;cache_be_used++;
		ed[cache_be_used>1024]();
	}
}

int analyse(int err_code){//output the error code 's meaning
	switch(err_code){
		case 1:
			cout<<"[Error]No args\nWhen `lbp` finds that there are not enough args,this error will occur.\n";
			break;
		case 2:
			cout<<"[Error]system error\nF--king your system,cause your system made a error.\n";
			break;
		case 3:
			cout<<"[Error]No this error code\nWhen you use `lbp err [a not existing error code]`,this error will occur.\n";
			break;
		case 4:
			cout<<"[Error]Undefined token\nWhen we found a undefined token,this error will occur.\n";
			break;
		default:
			return 3;
	}
	return 0;
}

void init(){
	//初始化tokens
	tokens["print"]=[]{
		++*line;
		types t=pexpl();
		function<void()> a=[&]{
			for(int i=0;i<t.size;i++){
				switch(t.data[i].ty){
					case 0:
						cout<<"()";
						break;
					case 1:
						cout<<t.data[i].data.c;
						break;
					case 2:
						cout<<t.data[i].data.i;
						break;
					case 5:
						cout<<t.data[i].data.cp;
						break;
					case 6:{
						types t0=t;
						t=*t.data[i].data.kids;
						a();
						t=t0;
						break;
					}
				}
			}
		};
		a();
		types t2;
		t2.data=new type[1];
		t2.size=1;
		litter.push_back(t2.data);
		t2.data[0].ty=0;// Unit/Void
		return t2;
	};
	tokens["ret"]=[]{
		++*line;
		types t=pexpl();
		throw t;
		
		types t2;
		t2.data=new type[1];
		t2.size=1;
		litter.push_back(t2.data);
		t2.data[0].ty=0;// Unit/Void
		return t2;
	};
	tokens["}"]=[]{
		types t2;
		t2.data=new type[1];
		t2.size=1;
		litter.push_back(t2.data);
		t2.data[0].ty=0;// Unit/Void
		throw t2;
		
		return t2;//emm... 这个其实可以去掉,但我没有支持c++14的编译器,会编译错误
	};
    //完善括号向量解析
    tokens["("]=[]{
        vector<types> elements;
        ++*line;  // 跳过 '('
        while(true){
            // 检查是否遇到结束括号
            if(*line>=ops.size()){
                cout << "Unmatched '(' !\n";
                break;
            }
            
            // 遇到结束括号
            if(ops[*line] == ")"){
                //++*line;  // 跳过 ')'
                /*Debug Logs
				 if we ++*line ,
				 then the line will ++ for twice,make the next command be crossed
				*/
                break;
            }
            
            // 解析当前表达式
            types expr=pexpl();
            elements.push_back(expr);
            ++*line;  // 移动到下一个token
        }
        
        // 创建向量类型
        types* inner=new types;
        inner->size=elements.size();
        inner->data=new type[inner->size];
        litter.push_back(inner);
        litter.push_back(inner->data);
        // 复制元素到向量
        for(int i=0;i<elements.size();i++) {
            if(elements[i].size>0){
                inner->data[i]=elements[i].data[0];
            }else{
                inner->data[i].ty=0;//Unit类型
            }
        }
        return *inner;
    };
    tokens["let"]=[]{
    	string &vn=ops[++*line];
    	++*line;
		return vm[vn]=pexpl();
	};
	tokens["debug"]=[]{
	    cout << "\n--- 调试信息 ---\n";
	    cout << "当前行号: " << *line << "/" << ops.size() << "\n";
	    cout<<"下个token: "<<ops[*line+1]<<"\n";
	    cout<<"将执行的token表:\n";
	    for(int i=1;i<=6;i++){
	    	if(*line+i>=ops.size()){
	    		break;
			}
	    	cout<<"["<<ops[*line+i]<<"]\n";
	    	/*
			Debug Logs:
			数组越界,so we should 
			>if(*line+i>=ops.size()){
	break;
}
			*/
		}
	    cout << "已定义变量:\n";
	    for(const auto &p: vm){
	        cout<<"  "<<p.first<<"\n";
	    }
	    cout << "----------------\n";
	    
	    return types{};
	};
	tokens["len"]=[]{
	    ++*line;
	    types list=pexpl();
	    types result;
	    result.data=new type[1];
	    result.size=1;
	    result.data[0].ty=2;//Integer
	    if(list.data[0].ty==6){//列表类型
	        result.data[0].data.i=list.data[0].data.kids->size;
	    }else{
	        result.data[0].data.i=list.size;
	    }
	    litter.push_back(result.data);
	    return result;
	};
	tokens["at"]=[]{
	    ++*line;
	    types list=pexpl();
	    ++*line;
	    types index=pexpl();
	    if(index.data[0].ty==2){
	        int idx=index.data[0].data.i;
	        if(idx>=0&&idx<list.size){
	            return types{&list.data[idx],1};
	        }
	    }
	    cout << "无效列表访问\n";
	    return types{};
	};
	tokens["aka"]=[]{
	    ++*line;
	    string oldToken=ops[*line];
	    ++*line;
	    string newToken=ops[*line];
	    if(tokens.find(oldToken)!=tokens.end()){
	        tokens[newToken]=tokens[oldToken];
	    }else{
	        cout<<"源token未定义: "<<oldToken<<endl;
	    }
	    return types{};
	};
	tokens["func"]=[]{
		++*line;
		string fn=ops[*line];
		if(ops[*line].find('(')!=ops[*line].npos){
			++*line;
			fn.erase(fn.size()-1,fn.size());
		}
		string an=ops[++*line];
		vector<string> av;
		while(an[0]!=')'){
			av.push_back(an);
			an=ops[++*line];
		}
		if(an.find('{')!=an.npos){
			--*line;
		}
		/*
		Debug Logs:
		Emm...
		```cpp
		if(an.find('{')==an.npos){
			++*line;
		}
		```
		if we use it (^),*line will ++ for twice.
		i don't know why.
		*/
		vm[fn].data=new type[av.size()+1];
		litter.push_back(vm[fn].data);
		vm[fn].data[0].data.i=++*line;
		vm[fn].data[0].ty=2;
		for(int i=1;i<av.size()+1;i++){
			vm[fn].data[i].data.cp=av[i-1].c_str();
			cout<<"{"<<vm[fn].data[i].data.cp<<":be not well}";
		}
		vm[fn].size=av.size()+1;
		int pc=1;
		while(pc){
			++*line;
			if(ops[*line].find("{")!=ops[*line].npos)pc++;
			else if(ops[*line].find("}")!=ops[*line].npos)pc--;
		}
		/*
		Debug Logs:
		```cpp
		int pc=1;
		while(pc){
			++*line;
			if(ops[*line].find("{")!=ops[*line].npos)pc++;
			else if(ops[*line].find("}")!=ops[*line].npos)pc--;
		}
		```
		i forgot to use it ...
		*/
		return vm[fn];
	};
	tokens["each"]=[]{
		++*line;
		types t=pexpl();
		function<void()> a=[&]{
			cout<<'(';
			for(int i=0;i<t.size;i++){
				cout<<' ';
				switch(t.data[i].ty){
					case 0:
						cout<<"()";
						break;
					case 1:
						cout<<t.data[i].data.c;
						break;
					case 2:
						cout<<t.data[i].data.i;
						break;
					case 5:
						cout<<t.data[i].data.cp;
						break;
					case 6:{
						types t0=t;
						t=*t.data[i].data.kids;
						a();
						t=t0;
						break;
					}
				}
			}
			cout<<" )";
		};
		a();
		types t2;
		t2.data=new type[1];
		t2.size=1;
		litter.push_back(t2.data);
		t2.data[0].ty=0;// Unit/Void
		return t2;
	};
	tokens["__next"]=[]{
		++*line;return pexpl();
	};
	tokens["to"]=[]{//to [a func] [the first arg] [...]
		++*line;
		int f_n_l=*line;
		types t=pexpl();
		int tl=t.data[0].data.i+1;
		int as=t.size-2;
		for(int i=0;i<as;i++){
			vm[/*ops[f_n_l]+".v."+*/t.data[i+2].data.cp]=tokens["__next"]();
		}
		int *tpl=line;
		line=&tl;
		types rt=explain();
		line=tpl;
		/*
		Debug Logs:
		oh,f**k,this bug spend i two hours,
		
		now it is 3 hours 
		
		but i don't know why,i just find something be forgot(and something didn't),so i let tl +1.
		and we shouldn't put '++*line' on the end of the lamble
		*/
		/*
		Debug Logs:
		we found a bug again,we can't use args in the function!!!
		and the `debug logs` are more than the codes in tokens["to"]!
		oh,i found the name is `ops[f_n_l]+".v."+t.data[i+1].data.cp`,
		i think maybe it can be clean?
		i try to make it = t.data[i+1].data.cp
		oh,it not just so ,and we should make  i+1 => i+2
		how bad ,that means my func is so bad that i had no choice but to change the codes of token `to`,
		and i know why i should int as=t.size-1; => int as=t.size-2;
		*/
		/*
		雪崩的时候没有一片雪花是无辜的，func和to都是勾石 (pexpl可能也有问题 
		*/
		for(int i=0;i<as;i++){
			vm.erase(/*ops[f_n_l]+".v."+*/t.data[i+2].data.cp);
		}
		return rt;
	};
	tokens["set"]=[]{
    	string &vn=ops[++*line];
    	types post=tokens["__next"]();
    	types nv=tokens["__next"]();
    	for(int i=0;i<post.size;i++){
    		vm[vn].data[post.data[i].data.i]=nv.data[i];
		}
		return vm[vn];
	};
    auto extract_integer = [](types t) -> int {
        while (t.size == 1 && t.data[0].ty == 6) { // 解包向量类型
            t = *t.data[0].data.kids;
        }
        if (t.size == 1 && t.data[0].ty == 2) {
            return t.data[0].data.i;
        }
        cout << "Error: Operator requires integers.\n";
        exit(4);
    };

    // 通用二元运算符工厂函数
    auto make_binary_op = [extract_integer](function<int(int,int)> op, const string& op_name) -> function<types()> {
        return [op, op_name, extract_integer] {
            ++*line; // 移动到第一个操作数
            types op1 = pexpl();
            ++*line; // 移动到第二个操作数
            types op2 = pexpl();

            int a = extract_integer(op1);
            int b = extract_integer(op2);

            // 特殊错误检查（除法和取模）
            if (op_name == "/" || op_name == "%") {
                if (b == 0) {
                    cout << "Error: Division by zero.\n";
                    exit(4);
                }
            }

            int result = op(a, b);

            types t_result;
            t_result.data = new type[1];
            t_result.size = 1;
            litter.push_back(t_result.data);
            t_result.data[0].ty = 2; // 整数类型
            t_result.data[0].data.i = result;
            return t_result;
        };
    };

    // 注册算术运算符
    tokens["+"] = make_binary_op([](int a, int b) { return a + b; }, "+");
    tokens["-"] = make_binary_op([](int a, int b) { return a - b; }, "-");
    tokens["*"] = make_binary_op([](int a, int b) { return a * b; }, "*");
    tokens["/"] = make_binary_op([](int a, int b) { return a / b; }, "/");
    tokens["%"] = make_binary_op([](int a, int b) { return a % b; }, "%");

    // 注册比较运算符（返回0/1）
    tokens[">"] = make_binary_op([](int a, int b) { return a > b; }, ">");
    tokens["<"] = make_binary_op([](int a, int b) { return a < b; }, "<");
    tokens["=="] = make_binary_op([](int a, int b) { return a == b; }, "==");

    // 注册运算符别名
    tokens["add"] = tokens["+"];
    tokens["sub"] = tokens["-"];
    tokens["mul"] = tokens["*"];
    tokens["div"] = tokens["/"];
    tokens["mod"] = tokens["%"];
    tokens["gt"] = tokens[">"];
    tokens["lt"] = tokens["<"];
    tokens["eq"] = tokens["=="];
	
	tokens["pnt"]=tokens["print"];//the first short one;
	tokens[":="]=tokens["let"];
	tokens["fn"]=tokens["func"];
	tokens["pv"]=tokens["pa"]=tokens["each"];
	//the last short one;
	
	#ifdef PSTATE //Pstate (EsoLang)
	tokens["(("]=tokens["print"];
	tokens[")("]=tokens["ret"];
	tokens["))"]=tokens["let"];
	tokens["((("]=tokens["debug"];
	tokens["(()"]=tokens["len"];
	tokens["()("]=tokens["at"];
	tokens["())"]=tokens["aka"];
	tokens[")(("]=tokens["func"];
	tokens[")()"]=tokens["each"];
	tokens["))("]=tokens["to"];
	tokens["(((("]=tokens["set"];
	#endif
}

void clean(){
	for(auto& vp:litter){
		if(vp)delete[](char*)vp;
	}
	litter.clear();
}

int main(int ac,char **av){
	switch(ac){
		case 0:{
			cout<<"???\nimpossible!!!\n";
			return 2;
			break;
		}
		case 1:{
			cout<<"Usage: lbp [.lbp]\nOr: lbp err [error code]";
			return 1;
			break;
		}
		case 3:{
			if(string("err")==av[1]){
				return analyse(atoi(av[2]));
			}
			break;
		}
	};
	ifstream ifp(av[1]);
	string temp,t2;bool str=0;
	init();
	while(getline(ifp,temp)){
		for(const auto &ch:temp){
			if(ch=='\"'||ch=='\''){
				str=!str;
				t2+=string(1,ch);
			}else if(!str&&ch==' '){
				if(!t2.empty()){
					ops.push_back(t2);
					t2="";
				}
			}else if(ch==';'){
				break;
			}else{
				t2+=string(1,ch);
			}
		}
		if(!t2.empty()){
			ops.push_back(t2);
			t2="";
		}
	}
	ops.push_back("ret");
	ops.push_back("0");
	int _line=0;
	line=&_line;
	types result = explain();
	int ret_val = result.data[0].ty == 2 ? result.data[0].data.i : 0;
	clean();
	return ret_val;
}

/*
记得debug*/